<?php

namespace app\acc\controller;


use app\common\logic\LiXinLogic;
use app\common\model\UserMiner;
use think\Cache;
use think\Controller;
use think\Db;
use think\Exception;

class TaskAuto extends Controller {

    /**
     * 定时任务
     * 1.开启矿机
     * 2.关闭矿机
     * 3.会员等级检测
     * 4.自动领取收益
     * */

    //1.开启矿机
    public function startKj(){
        return Db::name('user_miner')
            ->where([
                'is_start' => 1,
                'status' => 1,
            ])
            ->update(['is_start' => 1]);
    }

    //2.关闭矿机
    public function endKj(){
        return Db::name('user_miner')
            ->where([
                'is_start' => 1,
                'status' => 1,
            ])
            ->update(['is_start' => 0]);
    }

    //3.查找会员，自动升级
    public function incMember(){
        //等级列表
        $levelList = Db::name('world_level')->select();
        //等级总数
        $levelCount = count($levelList);
        //查询所有用户
        $memberList = Db::name('member')->field(['id','level','parentId','path'])->select();
        $countMember = count($memberList);
        for ($i = 0 ;$i < $countMember;$i++){
            //计算该用户下的直推人数
            $leaderCount = Db::name('member')->alias('m')
                ->join('user_miner um','um.user_id = m.id','left')
                ->where(['m.parentId' => $memberList[$i]['id']])
                ->count();
            //计算该用户下面的团队人数
            if ($memberList[$i]['path']) {
                $path = $memberList[$i]['path'].','.$memberList[$i]['id'];
            } else {
                $path = $memberList[$i]['id'];
            }
            $teamCount = Db::name('member')->alias('m')
                ->join('user_miner um','um.user_id = m.id','left')
                ->where(['m.path' => ['like', '%'.$path.'%']])
                ->count();
            //判断用户等级
            $userLevel = 1;
            for ($l = 0;$l < $levelCount; $l++){
                //如果直推用户和团队人数大于等级人数，继续查找下一等级
                if ($leaderCount >= $levelList[$l]['direct_people']){
                    if ($teamCount >= $levelList[$l]['team_people']){
                        $userLevel = $levelList[$l]['level_id'];
                        continue;
                    }else{
                        $userLevel = ($levelList[$l]['level_id'] - 1) <= 0 ? 1 : ($levelList[$l]['level_id'] - 1);
                        break;
                    }
                }else{
                    $userLevel = ($levelList[$l]['level_id'] - 1) <= 0 ? 1 : ($levelList[$l]['level_id'] - 1);
                    break;
                }
            }
            Db::name('member')->where('id', $memberList[$i]['id'])->update(['level' => $userLevel]);
            //继续执行循环
            echo "执行第：{$i}条数据，用户id：{$memberList[$i]['id']}，直推人数：{$leaderCount}，团队人数：{$teamCount}，用户等级id为：{$userLevel} <br/><br/>";
            unset($memberList[$i]);
        }
    }

    //4.自动领取矿机收益
    public function profit($page = 0)
    {
        $countUserMiner = Db::name('user_miner')->count();
        $allPage = $countUserMiner / 1000;
        $tmpArr = [];
        Cache::rm(':tmpParentProfit');
        for ($i = 0; $i < $allPage; $i++) {
            $page = $i * 1000;
            $userMiners = Db::name('user_miner')->alias('m')
                ->field(['m.*','u.id as uid','u.miner','u.parentId','u.kj_all_token','u.level','u.all_receive'])
                ->join('member u','m.user_id = u.id','left')
                ->limit($page, 1000)->select();
            $update_user_miner = [];    //更新user_miner表
            $update_member = [];        //更新用户表信息
            $profitData = [];           //收益日志表
            $minerLogData = [];         //收益日志表
            $tmpProfitArr = [];               //存储收益数据
            try {
                Db::startTrans();
                foreach ($userMiners as $k => $v) {
                    //计算当前收益
                    if ($v['status'] == 1 && $v['is_start'] == 1) {
                        //矿机收益 = 矿机token * 矿机生产速度
                        if ($v['all_receive'] >= $v['miner_price']){
                            //收益等于实际投资金额，降低为千分之五
                            $kj_tokem_speed = $v['kj_token_speed'] / 100 * 0.5;
                        }else{
                            //收益不等，按正常速度
                            $kj_tokem_speed = $v['kj_token_speed'] / 100;
                        }
                        //计算当前矿机收益
                        $profit = $v['miner_price'] * $kj_tokem_speed;
                        //用户购买矿机剩余token
                        $after_kj_token = $v['kj_all_token'] - $profit;
                        $kj_pre_token = $v['kj_pre_token'];
                        $status = $v['status'];
                        //矿机token不足时，检测是否存有预存token
                        if ($after_kj_token <= 0){
                            if ($v['kj_pre_token'] > 0){
                                //有预存token
                                $after_kj_token = $v['kj_all_token'] + $v['kj_pre_token'] - $profit;
                                $kj_pre_token = 0;
                            }else{
                                //不存在预存token
                                $status = 2;
                                $after_kj_token = 0;
                            }
                        }
                        //更新用户user_miner表数据
                        $update_user_miner[] = [
                            'id' => $v['id'],
                            'start_days' => $v['start_days'] + 1,
                            'kj_token' => $after_kj_token,
                            'kj_already_token' => $v['kj_already_token'] + $profit,
                            'receive' => $v['receive'] + $profit,
                            'receive_time' => time(),
                            'kj_pre_token' => $kj_pre_token,
                            'status' => $status
                        ];
                        //更新member数据
                        $update_member[] = [
                            'id' => $v['user_id'],
                            'kj_all_token' => $after_kj_token,
                            'miner' => $v['miner'] + $profit,
                            'all_receive' => $v['all_receive'] + $profit
                        ];
                        //添加收益日志记录
                        $profitData[] = [
                            'user_id' => $v['user_id'],
                            'miner_id' => $v['id'],
                            'profit' => $profit,
                            'times' => 24,
                            'add_time' => time(),
                            'after_miner_receive' => $v['kj_already_token'] + $profit
                        ];
                        //收益日志记录2
                        $minerLogData[] = [
                            'reflectId' => date("md",time()).$v['user_id'],
                            'userId' => $v['user_id'],
                            'type' => 6,
                            'num' => $profit,
                            'before' => $v['miner'],
                            'after' => $v['miner'] + $profit,
                            'desc' => '矿机收益',
                            'createTime' => now_datetime(),
                            'updateTime' => now_datetime(),
                        ];
                        $tmpProfitArr[] = [
                            'parentId' => $v['parentId'],
                            'profit' => $profit,
                            'miner_id' => $v['id']
                        ];
                    }
                }
                $minerModel = new UserMiner();
                $res_updateUserMiner = $minerModel->saveAll($update_user_miner);
                $memberModel = new \app\common\model\Member();
                $res_updateUser = $memberModel->saveAll($update_member);
                $insertProfit = Db::name('miner_profit')->insertAll($profitData);
                $insertMinerLog = Db::name('minerlog')->insertAll($minerLogData);
                if (!empty($res_updateUserMiner) && !empty($res_updateUser) && $insertProfit && $insertMinerLog) {
                    Db::commit();
                    $tmpArr = array_merge($tmpArr, $tmpProfitArr);
                } else {
                    Db::rollback();
                }
            }catch (Exception $e){
                Db::rollback();
                var_dump($e);
            }
            echo "{$i}<br/>";
        }
        Cache::set(':tmpParentProfit', $tmpArr,'7200');
    }

    //5.联合自创始人分摊收益
    public function avageProfit(){
        $list = Db::name('member')->field('id,parentId,level,miner,kj_all_token,all_receive')->select();
        $arr = [];  //联合创始人数组
        $arrCount = 0;  //联合创始人总数
        foreach ($list as $k=>$v){
            //计算是否达标联合创始人
            $leadCount = Db::name('member')->field('id,parentId,level,miner,kj_all_token,all_receive')->where(['parentId' => $v['id'],'level'=>4])->count();
            if ($leadCount >= 3){
                Db::name('member')->where(['id' => $v['id']])->update(['lh_name' => 1]);
                $arrCount += 1;
                $arr[$k] = $v;
            }
        }
        echo "联合创始人数：{$arrCount} <br/>";
        //计算当天收益
        $start = date("Y-m-d") . ' 00:00:00';
        $end = date("Y-m-d") . ' 23:59:59';
        /*$where['add_time'] = [ '>=', strtotime($start)];
        $where['add_time'] = [ '<=', strtotime($end)];*/
        $countMinerPrice = Db::name('user_miner')->whereBetween('add_time',[strtotime($start),strtotime($end)])->sum('miner_price');
        echo "当天收益：{$countMinerPrice} <br/>";
        //计算当天矿机收益
        if ($countMinerPrice > 0 && $arrCount > 0){
            //计算平均收益
            $aveg =  ($countMinerPrice * 0.001) / $arrCount;
            //循环联合创始人
            foreach ($arr as $ket=>$val){
                echo "联合创始人：{$val['id']}，平均收益：{$aveg}<br/>";
                //增加联创收益
                if ($val['kj_all_token'] - $aveg > 0){
                    $minerCount = $val['miner'] + $aveg;
                    minerlog(777, $val['id'], $aveg, 6, $val['miner'],$minerCount,'联创收益');
                    $memberData['all_receive'] = $val['all_receive'] + $aveg;
                    $memberData['miner'] = $minerCount;
                    $memberData['kj_all_token'] = $val['kj_all_token'] - $aveg;
                    Db::name('member')->where('id', $val['id'])->update($memberData);
                    $userMiner = Db::name('user_miner')->where('user_id', $val['id'])->find();
                    Db::name('user_miner')->where('user_id', $val['id'])->update(['kj_token' => ($userMiner['kj_token'] - $aveg)]);
                }

            }
        }

    }

    //6.矿机计算用户上级收益
    public function parentProfit()
    {
        $profitList = Cache::get(':tmpParentProfit');
        if (!$profitList){
            echo '数据为空！';die();
        }
//        try {
            foreach ($profitList as $k=>$v){
               $res = $this->distribuParent($v['parentId'], $v['profit'], $v['miner_id']);
               if (!$res){
                   echo '上级收益失败,订单id：'.$v['miner_id'];
               }
               unset($profitList[$k]);
            }
            Cache::rm(':tmpParentProfit');
            /*Cache::rm(':cache_update_member');
            Cache::rm(':cache_update_userMiner');
            Cache::rm(':cache_minerLogData');*/
            echo '上级收益成功！';
        /*}catch (Exception $e){
            var_dump($e);
            echo '上级收益失败！';
        }*/
    }

    public function distribuParent($parentId, $profit, $miner_id, $update_member = [], $update_userMiner = [], $minerLogData = [], $i = 1)
    {
        //查询上级用户
        $leader = Db::name('member')->field('id,parentId,isReal,miner,kj_all_token,level,all_receive')->where(['id' => $parentId])->find();
        if (!empty($leader) && $i <= 10) {
            if ($leader['isReal'] != 1) {
                return true;
            }
            //上级会获得收益的30%
            $receive = $profit * 0.3;
            //判断用户矿机是否满足收益，如果不是，返回
            $after = $leader['kj_all_token'] - $receive;
            if ($after >= 0){
                //减少矿机表里面的token
                $after_kj_token = $after;
                $update_member[] = [
                    'id' => $leader['id'],
                    'miner' => $leader['miner'] + $receive,
                    'kj_all_token' => $after_kj_token,
                    'all_receive' => $leader['all_receive'] + $receive
                ];
                $update_userMiner[] = [
                    'id' => $miner_id,
                    'kj_token' => $after_kj_token,
//                    'kj_pre_token' => $kj_pre_token,
//                    'status' => $status
                ];
                $minerLogData[] = [
                    'reflectId' => date("md",time()).$leader['id'],
                    'userId' => $leader['id'],
                    'type' => 6,
                    'num' => $receive,
                    'before' => $leader['miner'],
                    'after' => $leader['miner'] + $receive,
                    'desc' => '算力奖励',
                    'createTime' => now_datetime(),
                    'updateTime' => now_datetime(),
                ];
                $this->distribuParent($leader['parentId'], ($profit * 0.3), $miner_id, $update_member, $update_userMiner, $minerLogData, ($i+1));
            }else{
                $userMiner = Db::name('user_miner')->where(['user_id' => $parentId])->find();
                if ($userMiner['kj_pre_token'] > 0){
                    //有预存token
                    $after_kj_token = $leader['kj_all_token'] + $userMiner['kj_pre_token'] - $profit;
                    $kj_pre_token = 0;
                    $update_member[] = [
                        'id' => $leader['id'],
                        'miner' => $leader['miner'] + $receive,
                        'kj_all_token' => $after_kj_token,
                        'all_receive' => $leader['all_receive'] + $receive
                    ];
                    $update_userMiner[] = [
                        'id' => $miner_id,
                        'kj_token' => $after_kj_token,
                        'kj_pre_token' => $kj_pre_token,
                        'status' => 1
                    ];
                    $minerLogData[] = [
                        'reflectId' => date("md",time()).$leader['id'],
                        'userId' => $leader['id'],
                        'type' => 6,
                        'num' => $receive,
                        'before' => $leader['miner'],
                        'after' => $leader['miner'] + $receive,
                        'desc' => '算力奖励',
                        'createTime' => now_datetime(),
                        'updateTime' => now_datetime(),
                    ];
                    $this->distribuParent($leader['parentId'], ($profit * 0.3), $miner_id, $update_member, $update_userMiner, $minerLogData, ($i+1));
                }else{
                    //不存在预存token
                    $status = 2;
                    $after_kj_token = 0;
                    $update_member[] = [
                        'id' => $leader['id'],
                        'miner' => $leader['miner'] + $receive,
                        'kj_all_token' => $after_kj_token,
                        'all_receive' => $leader['all_receive'] + $receive
                    ];
                    $update_userMiner[] = [
                        'id' => $miner_id,
                        'kj_token' => $after_kj_token,
                        'kj_pre_token' => 0,
                        'status' => $status
                    ];
                    $minerLogData[] = [
                        'reflectId' => date("md",time()).$leader['id'],
                        'userId' => $leader['id'],
                        'type' => 6,
                        'num' => $receive,
                        'before' => $leader['miner'],
                        'after' => $leader['miner'] + $receive,
                        'desc' => '算力奖励',
                        'createTime' => now_datetime(),
                        'updateTime' => now_datetime(),
                    ];
                    return true;
                }
            }
        }else{
            $minerModel = new UserMiner();
            $res_updateUserMiner = $minerModel->saveAll($update_userMiner);
            $memberModel = new \app\common\model\Member();
            $res_updateUser = $memberModel->saveAll($update_member);
            $insertMinerLog = Db::name('minerlog')->insertAll($minerLogData);
            if (!empty($res_updateUserMiner) && !empty($res_updateUser) && $insertMinerLog) {
                return true;
            }else{
                return false;
            }
        }
        return true;
    }

}
